//todo 该组件没有写注释 需要补齐
//api文档地址https://vxetable.cn/#/table/api
<template>
  <div class="mytable-scrollbar">
    <vxe-table
      ref="xTree"
      size="mini"
      row-id="id"
      border
      :highlight-current-row="highlightCurrentRow"
      :auto-resize="true"
      :row-config="{ isHover: true }"
      :tree-config="{
        transform: true,
        rowField: 'id',
        parentField: 'pid',
        expandRowKeys: defaultExpandKeys,
        expandAll: isExpandAll,
        children: 'nodes',
        trigger: 'cell', //展开元素触发方式  	default（点击按钮触发）,cell（点击单元格触发）,row（点击行触发）default
      }"
      :checkbox-config="{ checkRowKeys, checkMethod: checkColumnMethod }"
      :menu-config="{
        enabled: isShowMenu,
        body: { options: bodyMenus, visibleMethod: menuVisibleMethod },
      }"
      :data.sync="tableData"
      :height="tableHeight ? tableHeight : 'auto'"
      :scroll-y="{ enabled: true }"
      :edit-config="editConfig"
      @current-change="onSelectedNode"
      @checkbox-change="handleCheckChange"
      @checkbox-all="handleCheckAll"
      @cell-click="handleCellClick"
      @cell-dblclick="handleCellDbClick"
      @menu-click="contextMenuClickEvent"
      @toggle-tree-expand="toggleTreeExpand"
      @edit-actived="editActivedEvent"
      @edit-closed="editClosedEvent"
    >
      >
      <vxe-column v-if="showCheckbox" type="checkbox" width="50" align="center" />
      <template v-for="(th, key) in tableHeader">
        <vxe-column
          v-if="th.render"
          :key="key"
          :field="th.prop"
          :title="th.label"
          :tree-node="key === 0"
          :width="th.width"
          :align="th.align"
          :cell-render="th.cellRender"
          :edit-render="th.editRender"
          :class-name="th.className"
        />
        <vxe-column
          v-else
          :key="key"
          :field="th.prop"
          :title="th.label"
          :tree-node="key === 0"
          :width="th.width"
          :align="th.align"
          show-overflow
          :edit-render="th.editRender"
          :class-name="th.className"
        >
          <template #default="{ row }">
            <span>
              <svg-icon
                v-if="showIcon && th.prop === iconProp"
                :icon-class="row.icon"
              />
              <span :style="{ color: row.color || 'black' }">{{
                row[th.prop]
              }}</span>
            </span>
          </template>
        </vxe-column>
      </template>
    </vxe-table>
  </div>

</template>

<script>
import { VXETable } from 'vxe-table'
export default {
  name: 'CompTreeTable',
  props: {
    // tableData
    tableData: {
      type: Array,
      default: () => {
        return []
      }
    },
    // tableHeader
    tableHeader: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 是否显示复选框
    showCheckbox: {
      type: Boolean,
      default: false
    },
    // 默认勾选的节点id
    checkRowKeys: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 是否默认展开所有行
    isExpandAll: {
      type: Boolean,
      default: false
    },
    // 默认展开的节点id
    defaultExpandKeys: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 树表高度
    tableHeight: {
      type: [Number, String],
      default: null
    },
    // 是否使用图标
    showIcon: {
      type: Boolean,
      default: false
    },
    // 图标属性名
    iconProp: {
      type: String,
      default: 'name'
    },
    // 复选框可选择的行
    checkColumnMethod: {
      type: Function,
      default() {
        return true
      }
    },
    // 是否显示菜单
    isShowMenu: {
      type: Boolean,
      default: false
    },
    // 菜单项
    bodyMenus: {
      type: Array,
      default: () => []
    },
    // 菜单右键各项disabled属性设置
    menuVisibleMethod: {
      type: Function,
      default: null
    },
    // 是否显示选中背景色
    highlightCurrentRow: {
      type: Boolean,
      default: true
    },
    // 编辑模式配置
    editConfig: {
      type: Object,
      default: () => {
        return { key: 'id', trigger: 'click', mode: 'cell' }
      }
    },
    // 开启编辑框时 编辑框显示事件
    editActivedEvent: {
      type: Function,
      default: () => {}
    },
    // 开启编辑框时 编辑框消失事件
    editClosedEvent: {
      type: Function,
      default: () => {}
    }
  },
  data() {
    return {
      maxHeight: this.getPageHeight()
    }
  },
  mounted() {
    if (this.isExpandAll) {
      this.$refs.xTree.setAllTreeExpand(true)
    }
    for (const item of this.tableHeader) {
      item.cellRender = {}
      item.cellRender.name = item.prop + Math.random() * 100
      VXETable.renderer.add(item.cellRender.name, {
        renderDefault(h, renderPots, { row, column }) {
          if (item.render) {
            return [item.render(h, { row, column })]
          } else {
            return [<span>{row[column.field]}</span>]
          }
        }
      })
    }
    // 初始化菜单
    if (this.isShowMenu) {
      this.$refs.xTree.menuConfug = {
        body: {
          options: this.bodyMenus,
          visibleMethod: this.menuVisibleMethod
        }
      }
    }
  },
  methods: {
    getPageHeight() {
      return (
        (window.innerHeight ||
          document.documentElement.clientHeight ||
          document.body.clientHeight) - 200
      )
    },
    // 菜单事件，默认会传入当前点击的节点
    contextMenuClickEvent({ menu, row, column, type }) {
      const node = this.getCurrentRecord()
      // 这里的type默认为 'body'
      this.$parent[menu.code](node)
      // this.$emit('menu-click', menu, row, column, type)
    },
    /** ************************************************* 事件 ******************************************************/
    // 当手动勾选并且值发生改变时触发的事件
    handleCheckChange(data) {
      // records:所有勾选的数据
      // row:当前操作的节点
      // checked:勾选or取消勾选
      this.$emit('checkbox-change', data.records, data.row, data.checked)
    },
    // 当手动勾选全选时触发的事件
    handleCheckAll(data) {
      // records:所有勾选的数据
      // checked:全or取消全选
      this.$emit('checkbox-all', data.records, data.checked)
    },
    // 单元格被点击时会触发该事件
    handleCellClick(data) {
      // row:被点击的单元格行数据
      // column:被点击的单元格列数据
      this.$emit('cell-click', data.row, data.column)
    },
    // 单元格被双击时会触发该事件
    handleCellDbClick(data) {
      this.$emit('cell-dblclick', data.row, data.column)
    },
    onSelectedNode({ row }) {
      this.$emit('onSelectedNode', row)
    },
    // 当树节点展开或收起时会触发该事件
    toggleTreeExpand({ row, column, expanded }) {
      if (row.icon) {
        if (expanded && row.icon === 'wenjianyi') row.icon = 'wenjianer'
        if (!expanded && row.icon === 'wenjianer') row.icon = 'wenjianyi'
      }
      this.$emit('toggle-row-expand', row, column, expanded)
    },
    /** ************************************************* 方法 ******************************************************/
    // 设置复选框的选中状态，可一次传入一条数据和多条数据
    setCheckboxRow(row, checked) {
      if (typeof row === 'object') {
        return this.$refs.xTree.setCheckboxRow([row], checked)
      } else return this.$refs.xTree.setCheckboxRow(row, checked)
    },
    // 获取高亮的当前行数据
    getCurrentRecord() {
      return this.$refs.xTree.getCurrentRecord()
    },
    // 获取当前已选中的行数据（当前列表，如果 isFull=true 则获取全表已选中的数据）
    getCheckboxRecords(isFull) {
      return this.$refs.xTree.getCheckboxRecords(isFull || false)
    },
    // 根据行的唯一主键获取行
    getRowById(id) {
      return this.$refs.xTree.getRowById(id)
    },
    // 获取半选状态的行数据（当前列表，如果 isFull=true 则获取全表已选中的数据）
    getCheckboxIndeterminateRecords(isFull) {
      return this.$refs.xTree.getCheckboxIndeterminateRecords(isFull || false)
    },
    // 删除复选框选中的行数据
    removeCheckboxRow() {
      return this.$refs.xTree.removeCheckboxRow()
    },
    // 删除当前行选中的行数据
    removeCurrentRow() {
      return this.$refs.xTree.removeCurrentRow()
    },
    // 获取节点id的子节点
    getChildNode(id) {
      const nodes = []
      const getChildNode = (id, nodes) => {
        for (const item of this.$refs.xTree.data) {
          if (item.pid === id && nodes.indexOf(item) === -1) {
            nodes.push(item)
            getChildNode(item.id, nodes)
          }
        }
      }
      getChildNode(id, nodes)
      return nodes
    },
    // 显示指定列
    showColumn(columnName) {
      this.$nextTick(() => {
        this.$refs.xTree.showColumn(
          this.$refs.xTree.getColumnByField(columnName)
        )
      })
    },
    // 隐藏指定列
    hideColumn(columnName) {
      this.$nextTick(() => {
        this.$refs.xTree.hideColumn(
          this.$refs.xTree.getColumnByField(columnName)
        )
      })
    },
    // 加载数据并清除所有状态（对于表格数据需要重载、局部更新被修改的数据）
    reloadData(data) {
      this.$refs.xTree.reloadData(data)
    },
    /** *
     * 插入数据
     */
    insert(row) {
      this.$refs.xTree.insert(row)
    },
    /** *
     * 指定位置插入数据
     */
    insertAt(row, index) {
      this.$refs.xTree.insertAt(row, index)
    },
    /**
     * 获取树的所有节点数据
     * return {Array}  返回一个节点数组
     */
    getNodes(nodes, res, map) {
      if (nodes === undefined) {
        const data = this.$refs.xTree.getTableData()
        nodes = data.tableData || []
        res = []
      }
      for (let i = 0; i < nodes.length; i++) {
        const node = nodes[i]
        res.push(node)
        if (node.nodes && node.nodes.length > 0) {
          this.getNodes(node.nodes, res, map)
        }
      }
      // 因为展开数据可能重复，所以这里去重
      return [...new Set(res)]
    },
    /**
     * 清空当前高亮状态
     */
    clearCurrentRow() {
      this.$refs.xTree.clearCurrentRow()
    },
    /**
     * 删除一行或多行数据
     * rows: Row | Array
     */
    remove(rows) {
      this.$refs.xTree.remove(rows)
    },
    /**
     * 修改数据后update
     */
    updateData() {
      this.$refs.xTree.updateData()
    }
  }
}
</script>

<style lang="scss" scoped>
.mytable-scrollbar {
  height: calc(100% - 50px);
  overflow: auto;
}

/*表格滚动条样式*/
.mytable-scrollbar ::-webkit-scrollbar {
  width: 7px;
  height: 7px;
}
/*滚动条的轨道*/
.mytable-scrollbar ::-webkit-scrollbar-track {
  background-color: #ededed;
}
/*滚动条里面的小方块，能向上向下移动*/
.mytable-scrollbar ::-webkit-scrollbar-thumb {
  background-color: #ccc;
  border-radius: 5px;
  border: 1px solid #ccc;
  box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.2);
}
.mytable-scrollbar ::-webkit-scrollbar-thumb:hover {
  background-color: #a8a8a8;
}
.mytable-scrollbar ::-webkit-scrollbar-thumb:active {
  background-color: #ccc;
}
/*边角，即两个滚动条的交汇处*/
.mytable-scrollbar ::-webkit-scrollbar-corner {
  background-color: #ededed;
}
.mytable-scrollbar {
  ::v-deep .vxe-body--row {
    > .vxe-body--column {
      height: 30px;
      padding-top: 0;
      padding-bottom: 0;
    }
    input.vxe-default-input {
      border: none;
    }
    input.vxe-default-input:focus,
    .vxe-input > input:focus {
      color: rgb(248, 86, 64);
    }
  }
}
</style>
